/*
 * $AIST_Release: 0.9.0 $
 * Copyright 2011 Information Technology Research Institute, National
 * Institute of Advanced Industrial Science and Technology
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package util

import scala.util.parsing.combinator.syntactical.StdTokenParsers
import scala.util.parsing.input.Positional

trait ParsersEx extends StdTokenParsers {

  class ParserEx[T](lhs: Parser[T]) {
    def ~< [U](rhs: => Parser[U]): Parser[T] = lhs <~ rhs
    def ^^^@ [U <: Positional](value: U) = positioned(lhs ^^^ value)
  }

  class Parser1Arg[T1](p: Parser[T1]) {
    def ^^@[U <: Positional](f: (T1) => U): Parser[U] = {
      positioned(p ^^ { x1 => f(x1) })
    }
  }

  class Parser2Arg[T1, T2](p: Parser[T1 ~ T2]) {
    def ^^@[U <: Positional](f: (T1, T2) => U): Parser[U] = {
      positioned(p ^^ { case x1 ~ x2 => f(x1, x2) })
    }
  }

  class Parser3Arg[T1, T2, T3](p: Parser[T1 ~ T2 ~ T3]) {
    def ^^@[U <: Positional](f: (T1, T2, T3) => U): Parser[U] = {
      positioned(p ^^ { case x1 ~ x2 ~ x3 => f(x1, x2, x3)})
    }
  }

  class Parser4Arg[T1, T2, T3, T4](p: Parser[T1 ~ T2 ~ T3 ~ T4]) {
    def ^^@[U <: Positional](f: (T1, T2, T3, T4) => U): Parser[U] = {
      positioned(p ^^ { case x1 ~ x2 ~ x3 ~ x4 => f(x1, x2, x3, x4)})
    }
  }

  class Parser5Arg[T1, T2, T3, T4, T5](p: Parser[T1 ~ T2 ~ T3 ~ T4 ~ T5]) {
    def ^^@[U <: Positional](f: (T1, T2, T3, T4, T5) => U): Parser[U] = {
      positioned(p ^^ { case x1 ~ x2 ~ x3 ~ x4 ~ x5=> f(x1, x2, x3, x4, x5)})
    }
  }

  class Parser6Arg[T1, T2, T3, T4, T5, T6](p: Parser[T1 ~ T2 ~ T3 ~ T4 ~ T5 ~ T6]) {
    def ^^@[U <: Positional](f: (T1, T2, T3, T4, T5, T6) => U): Parser[U] = {
      positioned(p ^^ { case x1 ~ x2 ~ x3 ~ x4 ~ x5 ~ x6 => f(x1, x2, x3, x4, x5, x6)})
    }
  }

  implicit def parserEx[T](p: Parser[T])                                                  = new ParserEx(p)
  implicit def parserEx(s: String)                                                        = new ParserEx(keyword(s))
  implicit def parser1Arg[T1](p: Parser[T1])                                              = new Parser1Arg(p)
  implicit def parser1Arg(s: String)                                                      = new Parser1Arg(keyword(s))
  implicit def parser2Arg[T1, T2](p: Parser[T1 ~ T2])                                     = new Parser2Arg(p)
  implicit def parser3Arg[T1, T2, T3](p: Parser[T1 ~ T2 ~ T3])                            = new Parser3Arg(p)
  implicit def parser4Arg[T1, T2, T3, T4](p: Parser[T1 ~ T2 ~ T3 ~ T4])                   = new Parser4Arg(p)
  implicit def parser5Arg[T1, T2, T3, T4, T5](p: Parser[T1 ~ T2 ~ T3 ~ T4 ~ T5])          = new Parser5Arg(p)
  implicit def parser6Arg[T1, T2, T3, T4, T5, T6](p: Parser[T1 ~ T2 ~ T3 ~ T4 ~ T5 ~ T6]) = new Parser6Arg(p)
}
